<script setup lang="tsx">
import {
  reactive,
  ref,
  unref,
  markRaw,
  shallowRef,
  provide,
  shallowReactive,
  type Component
} from 'vue'
import { ContentWrap } from '@/components/ContentWrap'
import { Search } from '@/components/Search'
import { Table } from '@/components/Table'
import Add from './component/Add.vue'
import Modify from './component/Modify.vue'
import Detail from './component/Detail.vue'
import { ElCollapseTransition, ElSwitch, ElMessage } from 'element-plus'
import { useTable } from '@/hooks/web/useTable'
import { CrudSchema, useCrudSchemas } from '@/hooks/web/useCrudSchemas'
import { useSearch } from '@/hooks/web/useSearch'
import { BaseButton } from '@/components/Button'
import {
  getListApi,
  getDetailApi,
  getSelectListApi,
  updateStatusApi,
  delApi,
  type Row
} from '@/api/product/list'
import { getListApi as getSelectListApiList } from '@/api/product/classification'

defineOptions({
  name: 'ProjectList'
})
const comId = reactive({
  Add: markRaw(Add),
  Modify: markRaw(Modify),
  Detail: markRaw(Detail)
})
const formatTreeSelectData = (data) => {
  return data.map((item) => ({
    value: item.id,
    label: item.name,
    children: item.children ? formatTreeSelectData(item.children) : null
  }))
}
const searchParams = ref()
const { searchRegister, searchMethods } = useSearch()
const { setSchema } = searchMethods
const searchUser = async (query) => {
  if (query && Object.values(query).every((item) => item !== '')) {
    setSchema([
      {
        field: 'id',
        path: 'componentProps.loading',
        value: true
      }
    ])
    const params = {
      ...query,
      field: 'id,name'
    }
    const res = await getSelectListApi(params)
    if (res) {
      setSchema([
        {
          field: 'id',
          path: 'componentProps.options',
          value: res.data.list.map((item) => {
            return {
              label: item.name,
              value: item.id
            }
          })
        }
      ])
    }
    setSchema([
      {
        field: 'id',
        path: 'componentProps.loading',
        value: false
      }
    ])
  }
}
const crudSchemas = reactive<CrudSchema[]>([
  {
    field: 'selection',
    search: { hidden: true },
    form: { hidden: true },
    detail: { hidden: true },
    table: { type: 'selection' }
  },
  {
    field: 'id',
    label: '商品ID',
    search: { hidden: true },
    form: { hidden: true },
    detail: { hidden: true }
  },
  {
    field: 'imgList',
    label: '商品图片',
    search: { hidden: true },
    form: { hidden: true },
    detail: { hidden: true }
  },
  {
    field: 'name',
    label: '商品名称',
    form: { hidden: true },
    detail: { hidden: true }
  },
  {
    field: 'goods_cate_id_two',
    label: '商品分类',
    search: {
      component: 'TreeSelect',
      componentProps: {
        on: {
          change: (val) => {
            searchParams.value.goods_cate_id_two = val
          }
        }
      },
      // 远程加载option
      optionApi: async () => {
        const res = await getSelectListApiList({ field: 'id,name,pid' })
        // 转换数据格式
        const formattedData = formatTreeSelectData(res.data.list)
        return formattedData
      }
    },
    detail: { hidden: true },
    formatter: (cellValue) => {
      return `${cellValue.goods_cate_name_one} / ${cellValue.goods_cate_name_two}`
    }
  },
  {
    field: 'unit',
    label: '单位',
    form: { hidden: true },
    search: { hidden: true },
    detail: { hidden: true }
  },
  {
    field: 'shelf_life',
    label: '保质期(天)',
    form: { hidden: true },
    search: { hidden: true },
    detail: { hidden: true }
  },
  {
    field: 'status',
    label: '状态',
    search: {
      component: 'Select',
      componentProps: {
        options: [
          {
            label: '上架',
            value: 1
          },
          {
            label: '下架',
            value: 2
          }
        ]
      }
    },
    form: { hidden: true },
    detail: { hidden: true },
    table: {
      width: '200px',
      slots: {
        default: ({ row }) => {
          return (
            <ElSwitch
              v-model={row.status}
              active-value={1}
              inactive-value={2}
              loading={switchLoading.value}
              beforeChange={() => changeStatus(row)}
            />
          )
        }
      }
    }
  },
  {
    field: 'create_time',
    label: '创建时间',
    search: { hidden: true },
    form: { hidden: true },
    detail: { hidden: true }
  },
  {
    field: 'update_time',
    label: '修改时间',
    search: { hidden: true },
    form: { hidden: true },
    detail: { hidden: true }
  },
  {
    field: 'racking_time',
    label: '商品上架时间',
    search: { hidden: true },
    form: { hidden: true },
    detail: { hidden: true }
  },
  {
    field: 'sold_out_time',
    label: '商品下架时间',
    search: { hidden: true },
    form: { hidden: true },
    detail: { hidden: true }
  },
  {
    field: 'action',
    width: '260px',
    label: '操作',
    search: { hidden: true },
    form: { hidden: true },
    detail: { hidden: true },
    table: {
      slots: {
        default: ({ row }) => {
          return (
            <>
              <BaseButton type="primary" onClick={() => modifyAction(row.id)}>
                编辑
              </BaseButton>
              <BaseButton type="primary" onClick={() => detailAction(row.id)}>
                详情
              </BaseButton>
            </>
          )
        }
      }
    }
  }
])
// @ts-ignore
const { allSchemas } = useCrudSchemas(crudSchemas)

const ids = ref<string[]>([])

const setSearchParams = (params: any) => {
  searchParams.value = params
  getList()
}

const { tableRegister, tableState, tableMethods } = useTable({
  fetchDataApi: async () => {
    const { currentPage, pageSize } = tableState
    const res = await getListApi({
      page: unref(currentPage),
      limit: unref(pageSize),
      ...unref(searchParams)
    })
    return {
      list: res.data.list.map((res) => {
        const resultArray = res.img.split(',')
        return {
          ...res,
          imgList: resultArray[0]
        }
      }),
      total: res.data.count
    }
  },
  fetchDelApi: async () => {
    const res = await delApi({ id: unref(ids).join(',') })
    return !!res
  }
})
const { loading, dataList, total, currentPage, pageSize } = tableState
const { getList, getElTableExpose, delList } = tableMethods

const showCollapse = ref(false)
let currentAction = shallowRef()
let currentRow = shallowReactive<any>({})
const action = (component: Component) => {
  currentAction.value = component
  if (showCollapse.value === false) showCollapse.value = true
}

const addAction = () => {
  Object.assign(currentRow, {
    id: '',
    name: '',
    img: '',
    unit: '',
    money: '',
    weight: '',
    goods_cate_id_two: '',
    descriptions: '',
    shelf_life: '',
    spec_type: '1',
    attrs: {},
    specs: [
      {
        spec_name: '',
        money: '',
        weight: '',
        purchasing_price: '',
        img: ''
      }
    ]
  })
  action(comId['Add'])
}

const modifyAction = async (id: number) => {
  const list = await getDetailApi({ id })
  const data = list.data.info
  const currentRowData = {
    id: data.id,
    name: data.name,
    img: data.img.split(','),
    unit: data.unit,
    shelf_life: data.shelf_life,
    descriptions: data.descriptions,
    goods_cate_id_two: data.goods_cate_id_two,
    spec_type: data.spec_type,
    money: '',
    weight: '',
    purchasing_price: '',
    spec: [],
    goods_rule: []
  }
  if (data.spec_type == 1) {
    currentRowData.money = data.goods_rule[0].money
    currentRowData.weight = data.goods_rule[0].weight
    currentRowData.purchasing_price = data.goods_rule[0].purchasing_price
  } else {
    currentRowData.spec = data.goods_spec.map((res) => {
      return {
        name: res.name,
        bool: true,
        count: 0,
        keys: res.value.split(',')
      }
    })
    currentRowData.goods_rule = data.goods_rule.map((item: any) => {
      const temp: any = {
        img: item.img,
        money: item.money,
        weight: item.weight,
        purchasing_price: item.purchasing_price,
        title: '',
        titleArray: []
      }
      const titles = data.goods_spec.map((item: any) => item.name)
      item.spec_name.split('|').forEach((val: any, index: number) => {
        var key = 'id' + titles[index]
        temp[key as keyof typeof temp] = val
        temp.titleArray.push(val)
      })
      temp.title = temp.titleArray.join('|')
      return temp
    })
  }
  Object.assign(currentRow, currentRowData)
  action(comId['Modify'])
}
const detailAction = async (id: number) => {
  const list = await getDetailApi({ id })
  const data = list.data.info
  const currentRowData = {
    id: data.id,
    name: data.name,
    img: data.img.split(','),
    unit: data.unit,
    shelf_life: data.shelf_life,
    descriptions: data.descriptions,
    goods_cate_id_two: data.goods_cate_id_two,
    spec_type: data.spec_type,
    money: '',
    weight: '',
    purchasing_price: '',
    spec: [],
    goods_rule: []
  }
  if (data.spec_type == 1) {
    currentRowData.money = data.goods_rule[0].money
    currentRowData.weight = data.goods_rule[0].weight
    currentRowData.purchasing_price = data.goods_rule[0].purchasing_price
  } else {
    currentRowData.spec = data.goods_spec.map((res) => {
      return {
        name: res.name,
        bool: true,
        count: 0,
        keys: res.value.split(',')
      }
    })
    currentRowData.goods_rule = data.goods_rule.map((item: any) => {
      const temp: any = {
        img: item.img,
        money: item.money,
        weight: item.weight,
        purchasing_price: item.purchasing_price,
        title: '',
        titleArray: []
      }
      const titles = data.goods_spec.map((item: any) => item.name)
      item.spec_name.split('|').forEach((val: any, index: number) => {
        var key = 'id' + titles[index]
        temp[key as keyof typeof temp] = val
        temp.titleArray.push(val)
      })
      temp.title = temp.titleArray.join('|')
      return temp
    })
  }
  Object.assign(currentRow, currentRowData)
  action(comId['Detail'])
}

const closeCollapse = () => {
  showCollapse.value = false
}

const delLoading = ref(false)

const delData = async (row: Row | null) => {
  const elTableExpose = await getElTableExpose()
  ids.value = row ? [row.id] : elTableExpose?.getSelectionRows().map((v: Row) => v.id) || []
  delLoading.value = true
  await delList(unref(ids).length).finally(() => {
    delLoading.value = false
  })
}

const switchLoading = ref(false)
const changeStatus = async (row) => {
  const val = {
    '1': 2,
    '2': 1
  }
  switchLoading.value = true
  try {
    const res = await updateStatusApi({ status: val[row.status], id: row.id })
    if (res) ElMessage.success(res.msg)
    return !!res
  } finally {
    switchLoading.value = false
  }
}

provide('currentRow', currentRow)
</script>

<template>
  <ContentWrap title="商品列表">
    <Search
      @register="searchRegister"
      :schema="allSchemas.searchSchema"
      @search="setSearchParams"
      @reset="setSearchParams"
    />

    <div class="mb-10px">
      <BaseButton type="primary" @click="addAction">新增</BaseButton>
      <BaseButton :loading="delLoading" type="danger" @click="delData(null)">删除</BaseButton>
    </div>

    <el-collapse-transition>
      <component
        :is="currentAction"
        @close="closeCollapse"
        @get-list="getList"
        v-if="showCollapse"
        :key="currentRow.id"
      />
    </el-collapse-transition>

    <Table
      v-model:pageSize="pageSize"
      v-model:currentPage="currentPage"
      :columns="allSchemas.tableColumns"
      :data="dataList"
      :loading="loading"
      :pagination="{ total }"
      :imagePreview="['imgList']"
      @register="tableRegister"
    />
  </ContentWrap>
</template>
